package com.nytimes.ohos.store.sample.data.model;


import com.google.common.base.Optional;
import com.google.gson.*;
import com.google.gson.reflect.*;
import com.google.gson.stream.*;
import java.io.IOException;
import java.util.List;

/**
 * A {@code TypeAdapterFactory} that handles all of the immutable types generated under {@code model}.
 * @see ImmutableRedditData
 * @see ImmutableData
 * @see ImmutablePost
 * @see ImmutableChildren
 * @see ImmutableImages
 * @see ImmutableImage
 * @see ImmutablePreview
 */
@SuppressWarnings("all")
public final class GsonAdaptersModel implements TypeAdapterFactory {
  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  @Override
  public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    if (RedditDataTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new RedditDataTypeAdapter(gson);
    }
    if (DataTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new DataTypeAdapter(gson);
    }
    if (PostTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new PostTypeAdapter(gson);
    }
    if (ChildrenTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new ChildrenTypeAdapter(gson);
    }
    if (ImagesTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new ImagesTypeAdapter(gson);
    }
    if (ImageTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new ImageTypeAdapter(gson);
    }
    if (PreviewTypeAdapter.adapts(type)) {
      return (TypeAdapter<T>) new PreviewTypeAdapter(gson);
    }
    return null;
  }

  @Override
  public String toString() {
    return "GsonAdaptersModel(RedditData, Data, Post, Children, Images, Image, Preview)";
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class RedditDataTypeAdapter extends TypeAdapter<RedditData> {
    private final Data dataTypeSample = null;
    private final TypeAdapter<Data> dataTypeAdapter;

    RedditDataTypeAdapter(Gson gson) {
      this.dataTypeAdapter = gson.getAdapter(TypeToken.get(Data.class));
    } 

    static boolean adapts(TypeToken<?> type) {
      return RedditData.class == type.getRawType()
          || ImmutableRedditData.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, RedditData value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writeRedditData(out, value);
      }
    }

    @Override
    public RedditData read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readRedditData(in);
    }

    private void writeRedditData(JsonWriter out, RedditData instance)
        throws IOException {
      out.beginObject();
      out.name("data");
      dataTypeAdapter.write(out, instance.data());
      out.name("kind");
      out.value(instance.kind());
      out.endObject();
    }

    private RedditData readRedditData(JsonReader in)
        throws IOException {
      ImmutableRedditData.Builder builder = ImmutableRedditData.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutableRedditData.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 'd':
        if ("data".equals(attributeName)) {
          readInData(in, builder);
          return;
        }
        break;
      case 'k':
        if ("kind".equals(attributeName)) {
          readInKind(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInData(JsonReader in, ImmutableRedditData.Builder builder)
        throws IOException {
      Data value = dataTypeAdapter.read(in);
      builder.data(value);
    }

    private void readInKind(JsonReader in, ImmutableRedditData.Builder builder)
        throws IOException {
      builder.kind(in.nextString());
    }
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class DataTypeAdapter extends TypeAdapter<Data> {
    private final Children childrenTypeSample = null;
    private final TypeAdapter<Children> childrenTypeAdapter;

    DataTypeAdapter(Gson gson) {
      this.childrenTypeAdapter = gson.getAdapter(TypeToken.get(Children.class));
    } 

    static boolean adapts(TypeToken<?> type) {
      return Data.class == type.getRawType()
          || ImmutableData.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, Data value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writeData(out, value);
      }
    }

    @Override
    public Data read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readData(in);
    }

    private void writeData(JsonWriter out, Data instance)
        throws IOException {
      out.beginObject();
      List<Children> childrenElements = instance.children();
      out.name("children");
      out.beginArray();
      for (Children e : childrenElements) {
        childrenTypeAdapter.write(out, e);
      }
      out.endArray();
      out.endObject();
    }

    private Data readData(JsonReader in)
        throws IOException {
      ImmutableData.Builder builder = ImmutableData.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutableData.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 'c':
        if ("children".equals(attributeName)) {
          readInChildren(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInChildren(JsonReader in, ImmutableData.Builder builder)
        throws IOException {
      if (in.peek() == JsonToken.BEGIN_ARRAY) {
        in.beginArray();
        while(in.hasNext()) {
          Children value = childrenTypeAdapter.read(in);
          builder.addChildren(value);
        }
        in.endArray();
      } else if (in.peek() == JsonToken.NULL) {
        in.nextNull();
      } else {
        Children value = childrenTypeAdapter.read(in);
        builder.addChildren(value);
      }
    }
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class PostTypeAdapter extends TypeAdapter<Post> {
    private final Preview previewTypeSample = null;
    private final Integer heightTypeSample = null;
    private final Integer widthTypeSample = null;
    private final Optional<Image> nestedThumbnailTypeSample = null;
    private final TypeAdapter<Preview> previewTypeAdapter;
    private final TypeAdapter<Integer> heightTypeAdapter;
    private final TypeAdapter<Integer> widthTypeAdapter;
    private final TypeAdapter<Optional<Image>> nestedThumbnailTypeAdapter;

    PostTypeAdapter(Gson gson) {
      this.previewTypeAdapter = gson.getAdapter(TypeToken.get(Preview.class));
      this.heightTypeAdapter = gson.getAdapter(TypeToken.get(Integer.class));
      this.widthTypeAdapter = gson.getAdapter(TypeToken.get(Integer.class));
      this.nestedThumbnailTypeAdapter = gson.getAdapter(new TypeToken<Optional<Image>>() {});
    } 

    static boolean adapts(TypeToken<?> type) {
      return Post.class == type.getRawType()
          || ImmutablePost.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, Post value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writePost(out, value);
      }
    }

    @Override
    public Post read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readPost(in);
    }

    private void writePost(JsonWriter out, Post instance)
        throws IOException {
      out.beginObject();
       Preview previewValue = instance.preview();
      if (previewValue != null) {
        out.name("preview");
        previewTypeAdapter.write(out, previewValue);
      } else if (out.getSerializeNulls()) {
        out.name("preview");
        out.nullValue();
      }
      out.name("title");
      out.value(instance.title());
      out.name("url");
      out.value(instance.url());
       Integer heightValue = instance.height();
      if (heightValue != null) {
        out.name("height");
        heightTypeAdapter.write(out, heightValue);
      } else if (out.getSerializeNulls()) {
        out.name("height");
        out.nullValue();
      }
       Integer widthValue = instance.width();
      if (widthValue != null) {
        out.name("width");
        widthTypeAdapter.write(out, widthValue);
      } else if (out.getSerializeNulls()) {
        out.name("width");
        out.nullValue();
      }
      out.name("nestedThumbnail");
      nestedThumbnailTypeAdapter.write(out, instance.nestedThumbnail());
      out.endObject();
    }

    private Post readPost(JsonReader in)
        throws IOException {
      ImmutablePost.Builder builder = ImmutablePost.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutablePost.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 'p':
        if ("preview".equals(attributeName)) {
          readInPreview(in, builder);
          return;
        }
        break;
      case 't':
        if ("title".equals(attributeName)) {
          readInTitle(in, builder);
          return;
        }
        break;
      case 'u':
        if ("url".equals(attributeName)) {
          readInUrl(in, builder);
          return;
        }
        break;
      case 'h':
        if ("height".equals(attributeName)) {
          readInHeight(in, builder);
          return;
        }
        break;
      case 'w':
        if ("width".equals(attributeName)) {
          readInWidth(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInPreview(JsonReader in, ImmutablePost.Builder builder)
        throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
      } else {
        Preview value = previewTypeAdapter.read(in);
        builder.preview(value);
      }
    }

    private void readInTitle(JsonReader in, ImmutablePost.Builder builder)
        throws IOException {
      builder.title(in.nextString());
    }

    private void readInUrl(JsonReader in, ImmutablePost.Builder builder)
        throws IOException {
      builder.url(in.nextString());
    }

    private void readInHeight(JsonReader in, ImmutablePost.Builder builder)
        throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
      } else {
        Integer value = heightTypeAdapter.read(in);
        builder.height(value);
      }
    }

    private void readInWidth(JsonReader in, ImmutablePost.Builder builder)
        throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
      } else {
        Integer value = widthTypeAdapter.read(in);
        builder.width(value);
      }
    }
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class ChildrenTypeAdapter extends TypeAdapter<Children> {
    private final Post dataTypeSample = null;
    private final TypeAdapter<Post> dataTypeAdapter;

    ChildrenTypeAdapter(Gson gson) {
      this.dataTypeAdapter = gson.getAdapter(TypeToken.get(Post.class));
    } 

    static boolean adapts(TypeToken<?> type) {
      return Children.class == type.getRawType()
          || ImmutableChildren.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, Children value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writeChildren(out, value);
      }
    }

    @Override
    public Children read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readChildren(in);
    }

    private void writeChildren(JsonWriter out, Children instance)
        throws IOException {
      out.beginObject();
      out.name("data");
      dataTypeAdapter.write(out, instance.data());
      out.endObject();
    }

    private Children readChildren(JsonReader in)
        throws IOException {
      ImmutableChildren.Builder builder = ImmutableChildren.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutableChildren.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 'd':
        if ("data".equals(attributeName)) {
          readInData(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInData(JsonReader in, ImmutableChildren.Builder builder)
        throws IOException {
      Post value = dataTypeAdapter.read(in);
      builder.data(value);
    }
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class ImagesTypeAdapter extends TypeAdapter<Images> {
    private final Image sourceTypeSample = null;
    private final TypeAdapter<Image> sourceTypeAdapter;

    ImagesTypeAdapter(Gson gson) {
      this.sourceTypeAdapter = gson.getAdapter(TypeToken.get(Image.class));
    } 

    static boolean adapts(TypeToken<?> type) {
      return Images.class == type.getRawType()
          || ImmutableImages.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, Images value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writeImages(out, value);
      }
    }

    @Override
    public Images read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readImages(in);
    }

    private void writeImages(JsonWriter out, Images instance)
        throws IOException {
      out.beginObject();
      out.name("source");
      sourceTypeAdapter.write(out, instance.source());
      out.endObject();
    }

    private Images readImages(JsonReader in)
        throws IOException {
      ImmutableImages.Builder builder = ImmutableImages.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutableImages.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 's':
        if ("source".equals(attributeName)) {
          readInSource(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInSource(JsonReader in, ImmutableImages.Builder builder)
        throws IOException {
      Image value = sourceTypeAdapter.read(in);
      builder.source(value);
    }
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class ImageTypeAdapter extends TypeAdapter<Image> {

    ImageTypeAdapter(Gson gson) {
    } 

    static boolean adapts(TypeToken<?> type) {
      return Image.class == type.getRawType()
          || ImmutableImage.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, Image value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writeImage(out, value);
      }
    }

    @Override
    public Image read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readImage(in);
    }

    private void writeImage(JsonWriter out, Image instance)
        throws IOException {
      out.beginObject();
      out.name("url");
      out.value(instance.url());
      out.name("height");
      out.value(instance.height());
      out.name("width");
      out.value(instance.width());
      out.endObject();
    }

    private Image readImage(JsonReader in)
        throws IOException {
      ImmutableImage.Builder builder = ImmutableImage.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutableImage.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 'u':
        if ("url".equals(attributeName)) {
          readInUrl(in, builder);
          return;
        }
        break;
      case 'h':
        if ("height".equals(attributeName)) {
          readInHeight(in, builder);
          return;
        }
        break;
      case 'w':
        if ("width".equals(attributeName)) {
          readInWidth(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInUrl(JsonReader in, ImmutableImage.Builder builder)
        throws IOException {
      builder.url(in.nextString());
    }

    private void readInHeight(JsonReader in, ImmutableImage.Builder builder)
        throws IOException {
      builder.height(in.nextInt());
    }

    private void readInWidth(JsonReader in, ImmutableImage.Builder builder)
        throws IOException {
      builder.width(in.nextInt());
    }
  }

  @SuppressWarnings({"unchecked", "raw"}) // safe unchecked, types are verified in runtime
  private static class PreviewTypeAdapter extends TypeAdapter<Preview> {
    private final Images imagesTypeSample = null;
    private final TypeAdapter<Images> imagesTypeAdapter;

    PreviewTypeAdapter(Gson gson) {
      this.imagesTypeAdapter = gson.getAdapter(TypeToken.get(Images.class));
    } 

    static boolean adapts(TypeToken<?> type) {
      return Preview.class == type.getRawType()
          || ImmutablePreview.class == type.getRawType();
    }

    @Override
    public void write(JsonWriter out, Preview value) throws IOException {
      if (value == null) {
        out.nullValue();
      } else {
        writePreview(out, value);
      }
    }

    @Override
    public Preview read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      return readPreview(in);
    }

    private void writePreview(JsonWriter out, Preview instance)
        throws IOException {
      out.beginObject();
      List<Images> imagesElements = instance.images();
      out.name("images");
      out.beginArray();
      for (Images e : imagesElements) {
        imagesTypeAdapter.write(out, e);
      }
      out.endArray();
      out.endObject();
    }

    private Preview readPreview(JsonReader in)
        throws IOException {
      ImmutablePreview.Builder builder = ImmutablePreview.builder();
      in.beginObject();
      while (in.hasNext()) {
        eachAttribute(in, builder);
      }
      in.endObject();
      return builder.build();
    }

    private void eachAttribute(JsonReader in, ImmutablePreview.Builder builder)
        throws IOException {
      String attributeName = in.nextName();
      switch (attributeName.charAt(0)) {
      case 'i':
        if ("images".equals(attributeName)) {
          readInImages(in, builder);
          return;
        }
        break;
      default:
      }
      in.skipValue();
    }

    private void readInImages(JsonReader in, ImmutablePreview.Builder builder)
        throws IOException {
      if (in.peek() == JsonToken.BEGIN_ARRAY) {
        in.beginArray();
        while(in.hasNext()) {
          Images value = imagesTypeAdapter.read(in);
          builder.addImages(value);
        }
        in.endArray();
      } else if (in.peek() == JsonToken.NULL) {
        in.nextNull();
      } else {
        Images value = imagesTypeAdapter.read(in);
        builder.addImages(value);
      }
    }
  }
}
